package rootkit

/*
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>

#include <string.h>
#include <stdbool.h>

bool is_promisc(char *name) {
	int promisc = false;
	int fd = socket(AF_INET, SOCK_DGRAM, 0);

	struct ifreq _ifr;
	strncpy(_ifr.ifr_name, name, IFNAMSIZ);

	// 获取flag信息
	if (ioctl(fd, SIOCGIFFLAGS, (char *)&_ifr) == -1) {
		promisc = false;
	}
	else if (_ifr.ifr_flags & IFF_PROMISC) {
		promisc = true;
	}

	close(fd);
	return promisc;
}

 */
import "C"
import (
	"net"
	"fmt"
	"cloud_worm/util/uexec"
)

// 对于机器interface的检查基本体现在promiscuous的检查上，主要表现为：
//		1. 通过ioctl，检查interface是否开启了promiscuous的mode；
//  	2. 如果ioctl检查出promiscuous mode，继而要检查ifconfig的显示
// 	结论：
//		1. 正常不建议开启，promiscuous mode
//		2. 如果开启promiscuous mode，但是ifconfig却看不到，则必然存在问题；

// 该rootkit的检查实际是确认 ifconfig 没问题

type InterfaceCheck struct {

}

func (i *InterfaceCheck) CheckInterfaces() error {

	if err := i.checkPromisc(); err != nil {
		return err
	}

	return nil
}

func (i *InterfaceCheck) checkPromisc() error {
	inters, err := net.Interfaces()
	if err != nil {
		return err
	}

	for _, item := range inters {
		promiscFlag, err := C.is_promisc(C.CString(item.Name))
		if err != nil {
			continue
		}

		if bool(promiscFlag) {
			ifConfigCmd := fmt.Sprintf("ifconfig %s | grep PROMISC > /dev/null 2>&1", item.Name)
			msg, ret := uexec.ExecUnixCmd(ifConfigCmd, 60)
			if ret != 0 {
				// TODO: 开启了promisc，且执行命令ifconfig出错，较严重告警
				fmt.Sprintf("exec'%s' error: %s", ifConfigCmd, msg)
			} else if msg == "" {
				// TODO: 开启了promisc，ifconfig中也有显示，一般告警
				fmt.Sprintf("promiscuous mode-%s:%v", item.Name, promiscFlag)
			} else {
				// TODO: 开启了promisc，ifconfig中不显示该promisc，严重告警
				fmt.Sprintf("promiscuous mode-%s:%v, buf ifconfig no showing it", item.Name, promiscFlag)
			}
		}
	}

	return nil
}